package com.yydream.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yydream.common.constant.GlobalEnums;
import com.yydream.common.constant.HttpStatus;
import com.yydream.common.utils.PageUtils;
import com.yydream.common.utils.R;
import com.yydream.dto.*;
import com.yydream.entity.SysRoleEntity;
import com.yydream.entity.SysRoleMenuEntity;
import com.yydream.entity.SysRoleUserEntity;
import com.yydream.entity.SysUserEntity;
import com.yydream.mapper.SysRoleMapper;
import com.yydream.service.SysRoleMenuService;
import com.yydream.service.SysRoleService;
import com.yydream.service.SysRoleUserService;
import com.yydream.service.SysUserService;
import com.yydream.vo.SysRoleVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRoleEntity> implements SysRoleService {

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysRoleUserService sysRoleUserService;

    @Autowired
    private SysUserService sysUserService;


    @Override
    public R queryById(Long id) {
        SysRoleVo sysRoleVo = new SysRoleVo();
        SysRoleEntity roleEntity = this.getById(id);
        if (Objects.nonNull(roleEntity)) {
            BeanUtils.copyProperties(roleEntity, sysRoleVo);
        }
        return R.ok().put( sysRoleVo);
    }

    @Override
    public R listPage(SysRolePageDTO req) {
        LambdaQueryWrapper<SysRoleEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(!StringUtils.isEmpty(req.getName()), SysRoleEntity::getName, req.getName())
                .eq(Objects.nonNull(req.getState()), SysRoleEntity::getState, req.getState());
        Page<SysRoleEntity> page = PageUtils.page(req);
        Page<SysRoleEntity> roleEntityPage = this.page(page, wrapper);
        Paging<SysRoleVo> dPaging = PageUtils.pageCopy(roleEntityPage, SysRoleVo.class);
        List<SysRoleVo> roleVoList = dPaging.getList().stream().map(c -> {
            c.setHiddenDelete(c.getId().equals(GlobalEnums.ADMIN_ROLE.getCode()) || c.getId().equals(GlobalEnums.NORMAL_ROLE.getCode()));
            LambdaQueryWrapper<SysRoleUserEntity> sysRoleUserEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sysRoleUserEntityLambdaQueryWrapper.eq(SysRoleUserEntity::getRoleId, c.getId());
            long count = sysRoleUserService.count(sysRoleUserEntityLambdaQueryWrapper);
            c.setUserNum(count);
            return c;
        }).collect(Collectors.toList());
        dPaging.setList(roleVoList);
        return R.ok().put( dPaging);
    }

    @Override
    public R insert(SysRoleDTO sysRole) {
        SysRoleEntity sysRoleEntity = new SysRoleEntity();
        BeanUtils.copyProperties(sysRole, sysRoleEntity);
        LambdaQueryWrapper<SysRoleEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleEntity::getName, sysRole.getName());
        List<SysRoleEntity> list = this.list(wrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            return R.error(HttpStatus.ALREADY_EXIST);
        }
        boolean save = this.save(sysRoleEntity);
        return R.ok().put( save);
    }

    @Override
    public R update(SysRoleDTO sysRole) {
        SysRoleEntity roleEntity = this.getById(sysRole.getId());
        if (Objects.isNull(roleEntity)) {
            return R.error(HttpStatus.DATA_NOT_EXIST);
        }
        BeanUtils.copyProperties(sysRole, roleEntity);
        LambdaQueryWrapper<SysRoleEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleEntity::getName, roleEntity.getName())
                .ne(SysRoleEntity::getId, roleEntity.getId());
        List<SysRoleEntity> list = this.list(wrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            return R.error(HttpStatus.ALREADY_EXIST);
        }
        boolean update = this.updateById(roleEntity);
        return R.ok().put( update);
    }

    @Override
    public R deleteById(Long[] ids) {
        List<SysRoleEntity> collect = Arrays.stream(ids).map(c -> {
            SysRoleEntity entity = new SysRoleEntity();
            entity.setId(c);
            return entity;
        }).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(collect)) {
            return R.error(HttpStatus.PARAM_ERROR);
        }
        List<Long> allIds = collect.stream().map(SysRoleEntity::getId).collect(Collectors.toList());
        if (allIds.contains(GlobalEnums.ADMIN_ROLE.getCode())) {
            return R.error("不能删除" + GlobalEnums.ADMIN_ROLE.getMsg());
        }
        if (allIds.contains(GlobalEnums.NORMAL_ROLE.getCode())) {
            return R.error("不能删除" + GlobalEnums.NORMAL_ROLE.getMsg());
        }
        boolean b = this.removeBatchByIds(collect);
        return R.ok().put( b);
    }

    @Transactional
    @Override
    public R roleRelationMenu(RoleRelationMenuDTO roleRelationMenuDTO) {
        Long roleId = roleRelationMenuDTO.getRoleId();
        List<SysRoleEntity> list = this.list(new LambdaQueryWrapper<SysRoleEntity>().eq(SysRoleEntity::getId, roleId));
        if (CollectionUtil.isEmpty(list)) {
            return R.error(HttpStatus.DATA_NOT_EXIST.getCode(), "角色ID: " + roleId + " 不存在");
        }
        List<Long> menuIds = roleRelationMenuDTO.getMenuIds();
        sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenuEntity>().eq(SysRoleMenuEntity::getRoleId, roleId));
        if (CollectionUtil.isEmpty(menuIds)) {
            return R.ok().put( null);
        }
        List<SysRoleMenuEntity> collect = menuIds.stream().map(c -> {
            SysRoleMenuEntity sysRoleMenuEntity = new SysRoleMenuEntity();
            sysRoleMenuEntity.setMenuId(c);
            sysRoleMenuEntity.setRoleId(roleId);
            return sysRoleMenuEntity;
        }).collect(Collectors.toList());
        boolean b = sysRoleMenuService.saveBatch(collect);
        return  R.ok().put( b);
    }

    @Override
    public R roleRelationMenuByRoleId(Integer roleId) {
        List<SysRoleMenuEntity> list = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenuEntity>()
                .eq(SysRoleMenuEntity::getRoleId, roleId));
        if (CollectionUtil.isEmpty(list)) {
            return R.ok().put( null);
        }
        List<Long> menuIds = list.stream().map(c -> c.getMenuId()).collect(Collectors.toList());
        return R.ok().put( menuIds);
    }

    @Transactional
    @Override
    public R roleRelationUser(RoleRelationUserDTO roleRelationUserDTO) {
        Long roleId = roleRelationUserDTO.getRoleId();
        List<SysRoleEntity> list = this.list(new LambdaQueryWrapper<SysRoleEntity>().eq(SysRoleEntity::getId, roleId));
        if (CollectionUtil.isEmpty(list)) {
            return R.error(HttpStatus.DATA_NOT_EXIST.getCode(), "角色ID: " + roleId + " 不存在");
        }
        List<Long> userIds = roleRelationUserDTO.getUserIds();
        sysRoleUserService.remove(new LambdaQueryWrapper<SysRoleUserEntity>().eq(SysRoleUserEntity::getRoleId, roleId));
        if (CollectionUtil.isEmpty(userIds)) {
            return R.ok().put( null);
        }
        LambdaQueryWrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysUserEntity::getId, userIds);
        List<SysUserEntity> list1 = sysUserService.list(queryWrapper);
        if (CollectionUtil.isEmpty(list1)) {
            return R.ok().put( null);
        }
        List<SysRoleUserEntity> collect = list1.stream().map(c -> {
            SysRoleUserEntity sysRoleUserEntity = new SysRoleUserEntity();
            sysRoleUserEntity.setUserId(c.getId());
            sysRoleUserEntity.setRoleId(roleId);
            return sysRoleUserEntity;
        }).collect(Collectors.toList());
        boolean b = sysRoleUserService.saveBatch(collect);
        return  R.ok().put( b);
    }

    @Override
    public R roleRelationUserByRoleId(Integer roleId) {
        List<SysRoleUserEntity> list = sysRoleUserService.list(new LambdaQueryWrapper<SysRoleUserEntity>()
                .eq(SysRoleUserEntity::getRoleId, roleId));
        if (CollectionUtil.isEmpty(list)) {
            return R.ok().put( null);
        }
        List<Long> userIds = list.stream().map(c -> c.getUserId()).collect(Collectors.toList());
        return R.ok().put( userIds);
    }
}
